/*******************************************************************************
 * Developer: Ian Doyle
 * Date:      6/23/2012
 *
 * All code Copyright (C) 2012 Ian Doyle. All rights reserved.
 *
 * This file is a part of FileFocus.
 *
 * FileFocus is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * FileFocus is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with FileFocus.  If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************/


package filefocus;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;

import filefocus.exception.FailedExecutionException;
import filefocus.exception.NonExecutableException;

public class ExecutablePlugin extends File {

	/**
	 * 
	 */
	private static final long serialVersionUID = -3302857006697450628L;

	public ExecutablePlugin(String pathname) throws NonExecutableException {
		super(pathname);
		checkForExecutable();
	}

	public ExecutablePlugin(URI uri) throws NonExecutableException {
		super(uri);
		checkForExecutable();
	}

	public ExecutablePlugin(String parent, String child) throws NonExecutableException {
		super(parent, child);
		checkForExecutable();
	}

	public ExecutablePlugin(File parent, String child) throws NonExecutableException {
		super(parent, child);
		checkForExecutable();
	}

	private void checkForExecutable() throws NonExecutableException {
		if(!canExecute())
			if(!this.setExecutable(true))
				throw new NonExecutableException(getPath() + " is non executable!");
	}
	
	public byte[] processFile(File fin) throws FailedExecutionException, IOException, InterruptedException {
		return processFile(fin, null);
	}
	
	public byte[] processFile(File fin, String[] supplementaryArgs) throws FailedExecutionException, IOException, InterruptedException {
		int supArgLen = (supplementaryArgs == null) ? 0 : supplementaryArgs.length; 
		String[] args = new String[2 + supArgLen];
		args[0] = getCanonicalPath();
		args[1] = fin.getCanonicalPath();
		for (int i = 0; i < supArgLen; ++i) {
			args[i+2] = supplementaryArgs[i];
		}
		Process digester = Runtime.getRuntime().exec(args);
		InputStream procStdout = digester.getInputStream();
		int exitVal = digester.waitFor();
		if(exitVal != 0)
			throw new FailedExecutionException(getAbsolutePath() + " terminated with a non-zero error code!");
		int availableBytes = procStdout.available();
		byte[] retval = new byte[availableBytes];
		int bytesRead = procStdout.read(retval, 0, availableBytes);
		if(bytesRead != availableBytes)
			throw new FailedExecutionException("Failed to read all information from " + getAbsolutePath() + "!");
		return retval;
	}
}
